package processingdata.ufo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;

import Control.Shape;
import Control.UFO;
import GUI.KeyComparator;
import GUI.MonthYearComparator;

public class Formatter {

	static ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>> wholeUfos = new ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>>();
	static ArrayList<UFO> ufos = new ArrayList<UFO>();
	static HashMap<String, HashMap> shapeSightings = new HashMap<String, HashMap>();

	public static void main(String[] args) throws IOException {

		loadData();
		System.out.println("finished loading");
		wholeUfos = processData();
		dumpData();

	}

	static void dumpData() {
		try {
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream(new File("data/newufos.ser")));
			oos.writeObject(wholeUfos);
			oos.close();

			for (int i = 0; i < wholeUfos.size(); i++) {
				// System.out.println(wholeUfos.get(i).size());
				ArrayList<ArrayList<ArrayList<UFO>>> yearList = wholeUfos
						.get(i);
				for (int j = 0; j < yearList.size(); j++) {
					ArrayList<ArrayList<UFO>> hourList = yearList.get(j);
					if (hourList != null) {

					}
					// System.out.println("\t"+yearList.get(j).size());
					for (int k = 0; k < yearList.get(j).size(); k++) {
						// System.out.println("\t\t"+yearList.get(j).get(k));
						for (int l = 0; l < yearList.get(j).get(k).size(); l++) {
							UFO ufo = yearList.get(j).get(k).get(l);
							// System.out.println(ufo.getCity());
						}
					}
				}
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	static ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>> processData() {
		System.out.println("in process data");
		int[] years = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		int[] months = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
		int[] days = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
				17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
		int[] hours = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
				16, 17, 18, 19, 20, 21, 22, 23 };
		ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>> tempList = new ArrayList<ArrayList<ArrayList<ArrayList<UFO>>>>();
		ArrayList<Shape> keyShapes = Shape.returnShapes();

		for (int i = 0; i < keyShapes.size(); i++) {
			Shape key = keyShapes.get(i);
			String keyStr = key.getName();

			if (shapeSightings.containsKey(keyStr)) {
				System.out.println("In map" + keyStr);
				HashMap<String, HashMap> yearMonthMap = shapeSightings
						.get(keyStr);

				// Set<String> yearMonthKeys=yearMonthMap.keySet();
				// Iterator<String> yearMonthIterator=yearMonthKeys.iterator();
				ArrayList<ArrayList<ArrayList<UFO>>> tempYearList = new ArrayList<ArrayList<ArrayList<UFO>>>();
				Set<String> yearMonthKeys = yearMonthMap.keySet();
				Iterator<String> yearMonthKeyIterator = yearMonthKeys
						.iterator();

				for (int y = 0; y < years.length; y++) {
					int year = years[y];
					for (int m = 0; m < months.length; m++) {
						int month = months[m];
						System.out.println("wat i am getting" + month + "/"
								+ year);

						String yearMonthKey = month + "/" + year;
						if (yearMonthMap.containsKey(yearMonthKey)) {
							System.out
									.println("contains " + month + "/" + year);

							HashMap<Integer, ArrayList<UFO>> tempIndex = new HashMap<Integer, ArrayList<UFO>>();
							HashMap<Integer, HashMap> dayMap = yearMonthMap
									.get(month + "/" + year);
							ArrayList<ArrayList<UFO>> finalUfoList = new ArrayList<ArrayList<UFO>>();
							for (int d = 0; d < days.length; d++) {

								int day = days[d];
								if (dayMap.containsKey(day)) {
									HashMap<Integer, ArrayList<UFO>> hourMap = dayMap
											.get(day);
									for (int h = 0; h < hours.length; h++) {
										int hour = hours[h];
										if (hourMap.containsKey(hour)) {
											ArrayList<UFO> ufoList = hourMap
													.get(hour);

											if (tempIndex.containsKey(hour)) {
												ArrayList<UFO> temporaryList = tempIndex
														.get(hour);
												for (int j = 0; j < ufoList
														.size(); j++) {
													temporaryList.add(ufoList
															.get(j));
												}

												tempIndex.put(hour,
														temporaryList);

											} else {
												ArrayList<UFO> temporaryList = new ArrayList<UFO>();
												for (int j = 0; j < ufoList
														.size(); j++) {
													temporaryList.add(ufoList
															.get(j));
												}

												tempIndex.put(hour,
														temporaryList);
											}
										}

									}
								}
							}
							for (int h = 0; h < hours.length; h++) {
								int hourKey = hours[h];
								if (tempIndex.containsKey(hourKey)) {
									ArrayList<UFO> temporaryList = tempIndex
											.get(hourKey);
									// for(int j=0;j<temporaryList.size();j++)
									// {
									// finalUfoList.add(temporaryList.get(j));
									// }

									finalUfoList.add(temporaryList);
									// System.out.println(finalUfoList.size());
								} else {
									ArrayList<UFO> temporaryList = new ArrayList<UFO>();
									finalUfoList.add(temporaryList);
								}
							}
							tempYearList.add(finalUfoList);
						} else {

							ArrayList<ArrayList<UFO>> temporaryList = new ArrayList<ArrayList<UFO>>();
							// for(int h=0;h<hours.length;h++)
							// {
							// temporaryList.add(null);
							// }
							tempYearList.add(temporaryList);
						}

					}
				}
				tempList.add(tempYearList);
			} else {
				ArrayList<ArrayList<ArrayList<UFO>>> tList = new ArrayList<ArrayList<ArrayList<UFO>>>();
				tempList.add(tList);
			}

			// while(yearMonthIterator.hasNext())
			// {
			// String yearMonthKey=yearMonthIterator.next();
			// HashMap<Integer,ArrayList<UFO>> hourMap=new
			// HashMap<Integer,ArrayList<UFO>>();
			// ArrayList<ArrayList<UFO>> hourList=new
			// ArrayList<ArrayList<UFO>>();
			// Set<Integer> hourKeys=hourMap.keySet();
			// Iterator<Integer> hourIterator=hourKeys.iterator();
			// while(hourIterator.hasNext())
			// {
			// int hourKey=hourIterator.next();
			// ArrayList<UFO> tempUfo=hourMap.get(hourKey);
			// hourList.add(tempUfo);
			// }
			// tempYearList.add(hourList);
			//
			// }
			// tempList.add(tempYearList);
			// }

		}
		return tempList;

	}

	static void loadData() {
		try {
			BufferedReader inputReader = new BufferedReader(new FileReader(
					new File("data/ufonew.data")));

			HashMap<String, Integer> shapeMap = new HashMap<String, Integer>();
			int uniqueIndex = 1000;
			while (inputReader.ready()) {

				String inputLine = inputReader.readLine();
				// System.out.println(inputLine);
				String[] inputLineParts = inputLine.split("\t");

				String date = inputLineParts[0].trim();
				int year = 0;
				int month = 0;
				int dayOfMonth = 0;
				int hourOfDay = 0;
				int minute = 0;

				if (date.contains(" ")) {
					String datePart = date.split(" ")[0].trim()
							.replaceAll("\\?", "").replaceAll("-", "");
					String timePart = date.split(" ")[1].trim();

					if (datePart.contains("/")) {
						if (datePart.split("/").length == 3) {
							// if(datePart.split("/")[0].matches("\\d*")&&datePart.split("/")[1].matches("\\d*")&&datePart.split("/")[2].matches("\\d*"))
							{
								if (datePart.split("/")[2].equals("")) {
									year = 0;
								} else {
									year = Integer
											.parseInt(datePart.split("/")[2]);
								}

								if (datePart.split("/")[0].equals("")) {
									month = 0;
								} else {
									month = Integer.parseInt(datePart
											.split("/")[0]);
								}
								if (datePart.split("/")[1].equals("")) {
									dayOfMonth = 0;
								} else {
									dayOfMonth = Integer.parseInt(datePart
											.split("/")[1]);
								}

							}

						}

					}

					if (timePart.contains(":")) {
						hourOfDay = Integer.parseInt(timePart.split(":")[0]);
						minute = Integer.parseInt(timePart.split(":")[1]);
					}

				}
				if (!(year >= 0 && year <= 10)) {
					continue;
				}
				if (inputLineParts.length != 9) {
					continue;
				}
				String city = inputLineParts[1];
				String state = inputLineParts[2];
				String shapeStr = inputLineParts[3];
				String duration = inputLineParts[4];
				String summary = inputLineParts[5];
				String posted = inputLineParts[6];
				float latitude = Float
						.parseFloat(inputLineParts[inputLineParts.length - 2]);
				float longitude = Float
						.parseFloat(inputLineParts[inputLineParts.length - 1]);
				int index;
				if (shapeMap.containsKey(shapeStr)) {
					index = shapeMap.get(shapeStr);
				} else {
					index = ++uniqueIndex;
					shapeMap.put(shapeStr, index);
				}
				GregorianCalendar dateOfSight = new GregorianCalendar(year,
						month - 1, dayOfMonth, hourOfDay, minute);
				processing.core.PVector coordinates = new processing.core.PVector(
						latitude, longitude);
				// System.out.println(shapeStr);
				ArrayList<Shape> shapes = Shape.returnShapes();
				UFO ufo = new UFO(coordinates, dateOfSight, shapes.get(Shape
						.getShapesEnumFromName(shapes, shapeStr).ordinal()),
						summary, duration, city, state,/*
														 * LONG SUMMARY TO BE
														 * INSERTED HERE
														 */"");
				shapeStr = shapes
						.get(Shape.getShapesEnumFromName(shapes, shapeStr)
								.ordinal()).getName();
				ufos.add(ufo);

				// System.out.println(month+"/"+year);
				if (shapeSightings.containsKey(shapeStr)) {
					HashMap<String, HashMap> yearMonthMap = shapeSightings
							.get(shapeStr);
					if (yearMonthMap.containsKey(month + "/" + year)) {

						HashMap<Integer, HashMap> dayMap = yearMonthMap
								.get(month + "/" + year);
						if (dayMap.containsKey(dayOfMonth)) {
							HashMap<Integer, ArrayList<UFO>> hourMap = (HashMap) dayMap
									.get(dayOfMonth);

							if (hourMap.containsKey(hourOfDay)) {
								ArrayList<UFO> ufoList = (ArrayList<UFO>) hourMap
										.get(hourOfDay);
								ufoList.add(ufo);
								hourMap.put(hourOfDay, ufoList);
							} else {
								ArrayList<UFO> ufoList = new ArrayList<UFO>();
								ufoList.add(ufo);
								hourMap.put(hourOfDay, ufoList);
							}
							dayMap.put(dayOfMonth, hourMap);
						} else {
							HashMap<Integer, ArrayList<UFO>> hourMap = new HashMap();
							ArrayList<UFO> ufoList = new ArrayList<UFO>();
							ufoList.add(ufo);
							hourMap.put(hourOfDay, ufoList);
							dayMap.put(dayOfMonth, hourMap);
						}
						yearMonthMap.put(month + "/" + year, dayMap);
					} else {
						HashMap<Integer, HashMap> dayMap = new HashMap();
						HashMap<Integer, ArrayList<UFO>> hourMap = new HashMap();
						ArrayList<UFO> ufoList = new ArrayList<UFO>();
						ufoList.add(ufo);
						hourMap.put(hourOfDay, ufoList);
						dayMap.put(dayOfMonth, hourMap);

						yearMonthMap.put(month + "/" + year, dayMap);

					}
					shapeSightings.put(shapeStr, yearMonthMap);

				} else {
					HashMap<String, HashMap> yearMonthMap = new HashMap();
					HashMap<Integer, HashMap> dayMap = new HashMap();
					HashMap<Integer, ArrayList<UFO>> hourMap = new HashMap();
					ArrayList<UFO> ufoList = new ArrayList<UFO>();
					ufoList.add(ufo);
					hourMap.put(hourOfDay, ufoList);
					dayMap.put(dayOfMonth, hourMap);
					yearMonthMap.put(month + "/" + year, dayMap);
					shapeSightings.put(shapeStr, yearMonthMap);

				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
